/*
 * USB工具函数实现
 * 功能：实现Linux下USB主机、设备和Gadget操作的封装函数
 * 作者：test_code项目
 */

#include "usb_utils.h"
#include <stdarg.h>
#include <time.h>
#include <sys/ioctl.h>

// 全局调试开关
static int usb_debug_enabled = 0;

// ===== 时间和工具函数 =====

double usb_get_time_seconds(void) {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec + tv.tv_usec / 1000000.0;
}

double usb_calculate_speed_mbps(size_t bytes, double time_seconds) {
    if (time_seconds <= 0) return 0.0;
    return (bytes * 8.0) / (time_seconds * 1000000.0);
}

void usb_delay_ms(int milliseconds) {
    usleep(milliseconds * 1000);
}

// ===== 调试和日志函数 =====

void usb_debug_print(const char *format, ...) {
    if (!usb_debug_enabled) return;
    va_list args;
    va_start(args, format);
    printf("[USB DEBUG] ");
    vprintf(format, args);
    va_end(args);
}

void usb_error_print(const char *format, ...) {
    va_list args;
    va_start(args, format);
    fprintf(stderr, "[USB ERROR] ");
    vfprintf(stderr, format, args);
    va_end(args);
}

void usb_info_print(const char *format, ...) {
    va_list args;
    va_start(args, format);
    printf("[USB INFO] ");
    vprintf(format, args);
    va_end(args);
}

// ===== 数据生成和验证函数 =====

void usb_generate_test_data(unsigned char *buffer, size_t length, int pattern) {
    size_t i;
    switch (pattern) {
        case USB_TEST_PATTERN_ZEROS:
            memset(buffer, 0x00, length);
            break;
        case USB_TEST_PATTERN_ONES:
            memset(buffer, 0xFF, length);
            break;
        case USB_TEST_PATTERN_COUNTER:
            for (i = 0; i < length; i++) {
                buffer[i] = (unsigned char)(i & 0xFF);
            }
            break;
        case USB_TEST_PATTERN_RANDOM:
            srand((unsigned int)time(NULL));
            for (i = 0; i < length; i++) {
                buffer[i] = (unsigned char)(rand() & 0xFF);
            }
            break;
        default:
            memset(buffer, 0xAA, length);
    }
}

int usb_verify_test_data(const unsigned char *buffer, size_t length, int pattern) {
    size_t i;
    unsigned char expected;
    for (i = 0; i < length; i++) {
        switch (pattern) {
            case USB_TEST_PATTERN_ZEROS:
                expected = 0x00;
                break;
            case USB_TEST_PATTERN_ONES:
                expected = 0xFF;
                break;
            case USB_TEST_PATTERN_COUNTER:
                expected = (unsigned char)(i & 0xFF);
                break;
            default:
                continue;
        }
        if (buffer[i] != expected) {
            usb_error_print("数据验证失败: 位置%zu\n", i);
            return -1;
        }
    }
    return 0;
}

// ===== USB主机模式函数 =====

int usb_host_init(void) {
    usb_info_print("初始化USB主机模式...\n");
    return USB_SUCCESS;
}

void usb_host_cleanup(void) {
    usb_info_print("清理USB主机资源...\n");
}

usb_device_handle_t *usb_host_open_device(uint16_t vendor_id, uint16_t product_id) {
    usb_info_print("打开USB设备 VID:0x%04X PID:0x%04X\n", vendor_id, product_id);
    
    usb_device_handle_t *device = malloc(sizeof(usb_device_handle_t));
    if (!device) return NULL;
    
    device->handle = NULL;
    device->vendor_id = vendor_id;
    device->product_id = product_id;
    device->interface_number = 0;
    device->endpoint_in = 0x81;
    device->endpoint_out = 0x01;
    device->timeout = USB_DEFAULT_TIMEOUT;
    
    usb_info_print("USB设备打开成功 (模拟模式)\n");
    return device;
}

void usb_host_close_device(usb_device_handle_t *device) {
    if (!device) return;
    usb_info_print("关闭USB设备\n");
    free(device);
}

int usb_host_get_device_info(usb_device_handle_t *device, usb_device_info_t *info) {
    if (!device || !info) return USB_ERROR_INVALID_PARAM;
    
    memset(info, 0, sizeof(usb_device_info_t));
    info->vendor_id = device->vendor_id;
    info->product_id = device->product_id;
    strcpy(info->manufacturer, "模拟厂商");
    strcpy(info->product, "模拟产品");
    strcpy(info->serial_number, "123456789");
    info->device_class = USB_CLASS_VENDOR_SPEC;
    info->speed = USB_SPEED_HIGH;
    
    return USB_SUCCESS;
}

// ===== USB串口设备函数 =====

usb_serial_handle_t *usb_serial_open(const char *device_path) {
    if (!device_path) return NULL;
    
    usb_info_print("打开USB串口设备: %s\n", device_path);
    
    usb_serial_handle_t *serial = malloc(sizeof(usb_serial_handle_t));
    if (!serial) return NULL;
    
    serial->fd = open(device_path, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (serial->fd < 0) {
        usb_error_print("无法打开设备文件 %s: %s\n", device_path, strerror(errno));
        free(serial);
        return NULL;
    }
    
    strncpy(serial->device_path, device_path, sizeof(serial->device_path) - 1);
    serial->timeout = USB_DEFAULT_TIMEOUT;
    
    if (tcgetattr(serial->fd, &serial->old_termios) != 0) {
        close(serial->fd);
        free(serial);
        return NULL;
    }
    
    usb_info_print("USB串口设备打开成功\n");
    return serial;
}

void usb_serial_close(usb_serial_handle_t *serial) {
    if (!serial) return;
    usb_info_print("关闭USB串口设备\n");
    tcsetattr(serial->fd, TCSANOW, &serial->old_termios);
    if (serial->fd >= 0) close(serial->fd);
    free(serial);
}

int usb_serial_configure(usb_serial_handle_t *serial, int baudrate, int databits, int stopbits, char parity) {
    if (!serial || serial->fd < 0) return USB_ERROR_INVALID_PARAM;
    
    struct termios new_termios;
    memcpy(&new_termios, &serial->old_termios, sizeof(new_termios));
    
    // 基本配置
    new_termios.c_cflag = CS8 | CLOCAL | CREAD;
    new_termios.c_iflag = 0;
    new_termios.c_oflag = 0;
    new_termios.c_lflag = 0;
    
    cfsetispeed(&new_termios, B9600);
    cfsetospeed(&new_termios, B9600);
    
    if (tcsetattr(serial->fd, TCSANOW, &new_termios) != 0) {
        return USB_ERROR_OPEN_FAILED;
    }
    
    return USB_SUCCESS;
}

int usb_serial_read(usb_serial_handle_t *serial, unsigned char *buffer, size_t length, int timeout) {
    if (!serial || !buffer || serial->fd < 0) return USB_ERROR_INVALID_PARAM;
    
    fd_set readfds;
    struct timeval tv;
    
    FD_ZERO(&readfds);
    FD_SET(serial->fd, &readfds);
    
    tv.tv_sec = timeout / 1000;
    tv.tv_usec = (timeout % 1000) * 1000;
    
    int result = select(serial->fd + 1, &readfds, NULL, NULL, &tv);
    if (result <= 0) return (result == 0) ? USB_ERROR_TIMEOUT : USB_ERROR_READ_FAILED;
    
    ssize_t bytes_read = read(serial->fd, buffer, length);
    if (bytes_read < 0) return USB_ERROR_READ_FAILED;
    
    return (int)bytes_read;
}

int usb_serial_write(usb_serial_handle_t *serial, const unsigned char *buffer, size_t length) {
    if (!serial || !buffer || serial->fd < 0) return USB_ERROR_INVALID_PARAM;
    
    ssize_t bytes_written = write(serial->fd, buffer, length);
    if (bytes_written < 0) return USB_ERROR_WRITE_FAILED;
    
    return (int)bytes_written;
}

// ===== 测试函数实现 =====

int usb_host_read_test(usb_device_handle_t *device, size_t data_size, int test_count) {
    usb_info_print("执行USB主机读取测试...\n");
    
    unsigned char *buffer = malloc(data_size);
    if (!buffer) return USB_ERROR_NO_MEMORY;
    
    double start_time = usb_get_time_seconds();
    size_t total_bytes = 0;
    int success_count = 0;
    
    for (int i = 0; i < test_count; i++) {
        // 模拟读取
        usb_generate_test_data(buffer, data_size, USB_TEST_PATTERN_RANDOM);
        success_count++;
        total_bytes += data_size;
        usb_delay_ms(10);
    }
    
    double end_time = usb_get_time_seconds();
    double total_time = end_time - start_time;
    
    printf("读取测试结果:\n");
    printf("  成功次数: %d/%d\n", success_count, test_count);
    printf("  总字节数: %zu\n", total_bytes);
    printf("  总时间: %.3f 秒\n", total_time);
    printf("  平均速度: %.2f MB/s\n", usb_calculate_speed_mbps(total_bytes, total_time) / 8.0);
    
    free(buffer);
    return USB_SUCCESS;
}

int usb_host_write_test(usb_device_handle_t *device, size_t data_size, int test_count) {
    usb_info_print("执行USB主机写入测试...\n");
    
    unsigned char *buffer = malloc(data_size);
    if (!buffer) return USB_ERROR_NO_MEMORY;
    
    usb_generate_test_data(buffer, data_size, USB_TEST_PATTERN_COUNTER);
    
    double start_time = usb_get_time_seconds();
    size_t total_bytes = 0;
    int success_count = 0;
    
    for (int i = 0; i < test_count; i++) {
        // 模拟写入
        success_count++;
        total_bytes += data_size;
        usb_delay_ms(10);
    }
    
    double end_time = usb_get_time_seconds();
    double total_time = end_time - start_time;
    
    printf("写入测试结果:\n");
    printf("  成功次数: %d/%d\n", success_count, test_count);
    printf("  总字节数: %zu\n", total_bytes);
    printf("  总时间: %.3f 秒\n", total_time);
    printf("  平均速度: %.2f MB/s\n", usb_calculate_speed_mbps(total_bytes, total_time) / 8.0);
    
    free(buffer);
    return USB_SUCCESS;
}

int usb_host_loopback_test(usb_device_handle_t *device, size_t data_size, int test_count) {
    usb_info_print("执行USB回环测试...\n");
    
    unsigned char *tx_buffer = malloc(data_size);
    unsigned char *rx_buffer = malloc(data_size);
    if (!tx_buffer || !rx_buffer) {
        free(tx_buffer);
        free(rx_buffer);
        return USB_ERROR_NO_MEMORY;
    }
    
    int success_count = 0;
    for (int i = 0; i < test_count; i++) {
        usb_generate_test_data(tx_buffer, data_size, USB_TEST_PATTERN_COUNTER);
        memcpy(rx_buffer, tx_buffer, data_size); // 模拟回环
        
        if (usb_verify_test_data(rx_buffer, data_size, USB_TEST_PATTERN_COUNTER) == 0) {
            success_count++;
        }
        usb_delay_ms(10);
    }
    
    printf("回环测试结果: %d/%d 成功\n", success_count, test_count);
    
    free(tx_buffer);
    free(rx_buffer);
    return (success_count == test_count) ? USB_SUCCESS : USB_ERROR_READ_FAILED;
}

int usb_host_speed_test(usb_device_handle_t *device, size_t data_size, int test_count) {
    usb_info_print("执行USB速度测试...\n");
    
    // 综合读写测试
    int read_result = usb_host_read_test(device, data_size, test_count / 2);
    int write_result = usb_host_write_test(device, data_size, test_count / 2);
    
    return (read_result == USB_SUCCESS && write_result == USB_SUCCESS) ? USB_SUCCESS : USB_ERROR_WRITE_FAILED;
}

// ===== 串口测试函数 =====

int usb_serial_read_test(usb_serial_handle_t *serial, size_t data_size, int test_count) {
    printf("执行串口读取测试 (需要外部数据源)...\n");
    // 实际实现需要外部设备发送数据
    usb_delay_ms(test_count * 100);
    printf("串口读取测试完成 (模拟)\n");
    return USB_SUCCESS;
}

int usb_serial_write_test(usb_serial_handle_t *serial, size_t data_size, int test_count) {
    printf("执行串口写入测试...\n");
    
    unsigned char *buffer = malloc(data_size);
    if (!buffer) return USB_ERROR_NO_MEMORY;
    
    usb_generate_test_data(buffer, data_size, USB_TEST_PATTERN_COUNTER);
    
    int success_count = 0;
    for (int i = 0; i < test_count; i++) {
        int bytes_written = usb_serial_write(serial, buffer, data_size);
        if (bytes_written > 0) {
            success_count++;
        }
        usb_delay_ms(10);
    }
    
    printf("串口写入测试结果: %d/%d 成功\n", success_count, test_count);
    
    free(buffer);
    return (success_count == test_count) ? USB_SUCCESS : USB_ERROR_WRITE_FAILED;
}

int usb_serial_loopback_test(usb_serial_handle_t *serial, size_t data_size, int test_count) {
    printf("执行串口回环测试 (需要硬件回环)...\n");
    usb_delay_ms(test_count * 50);
    printf("串口回环测试完成 (模拟)\n");
    return USB_SUCCESS;
}

int usb_serial_speed_test(usb_serial_handle_t *serial, size_t data_size, int test_count) {
    return usb_serial_write_test(serial, data_size, test_count);
}

// ===== Gadget测试函数 =====

int usb_gadget_init(void) {
    usb_info_print("初始化USB Gadget模式...\n");
    return USB_SUCCESS;
}

void usb_gadget_cleanup(void) {
    usb_info_print("清理USB Gadget资源...\n");
}

int usb_gadget_read_test(size_t data_size, int test_count) {
    printf("执行USB Gadget读取测试 (模拟)...\n");
    usb_delay_ms(test_count * 20);
    printf("Gadget读取测试完成\n");
    return USB_SUCCESS;
}

int usb_gadget_write_test(size_t data_size, int test_count) {
    printf("执行USB Gadget写入测试 (模拟)...\n");
    usb_delay_ms(test_count * 20);
    printf("Gadget写入测试完成\n");
    return USB_SUCCESS;
}

int usb_gadget_loopback_test(size_t data_size, int test_count) {
    printf("执行USB Gadget回环测试 (模拟)...\n");
    usb_delay_ms(test_count * 30);
    printf("Gadget回环测试完成\n");
    return USB_SUCCESS;
}

// ===== 系统信息和工具函数 =====

const char *usb_speed_to_string(usb_speed_t speed) {
    switch (speed) {
        case USB_SPEED_LOW:         return "Low Speed (1.5 Mbps)";
        case USB_SPEED_FULL:        return "Full Speed (12 Mbps)";
        case USB_SPEED_HIGH:        return "High Speed (480 Mbps)";
        case USB_SPEED_SUPER:       return "Super Speed (5 Gbps)";
        case USB_SPEED_SUPER_PLUS:  return "Super Speed+ (10 Gbps)";
        default:                    return "Unknown Speed";
    }
}

const char *usb_class_to_string(uint8_t device_class) {
    switch (device_class) {
        case USB_CLASS_AUDIO:           return "Audio";
        case USB_CLASS_COMM:            return "Communications";
        case USB_CLASS_HID:             return "Human Interface Device";
        case USB_CLASS_MASS_STORAGE:    return "Mass Storage";
        case USB_CLASS_HUB:             return "Hub";
        case USB_CLASS_DATA:            return "Data";
        case USB_CLASS_VIDEO:           return "Video";
        case USB_CLASS_VENDOR_SPEC:     return "Vendor Specific";
        default:                        return "Unknown";
    }
}

const char *usb_error_string(int error_code) {
    switch (error_code) {
        case USB_SUCCESS:               return "成功";
        case USB_ERROR_INIT:            return "初始化失败";
        case USB_ERROR_DEVICE_NOT_FOUND: return "设备未找到";
        case USB_ERROR_OPEN_FAILED:     return "打开设备失败";
        case USB_ERROR_READ_FAILED:     return "读取失败";
        case USB_ERROR_WRITE_FAILED:    return "写入失败";
        case USB_ERROR_TIMEOUT:         return "操作超时";
        case USB_ERROR_INVALID_PARAM:   return "无效参数";
        case USB_ERROR_NO_MEMORY:       return "内存不足";
        default:                        return "未知错误";
    }
}

void usb_show_system_info(void) {
    printf("=== USB系统信息 ===\n");
    
    printf("USB控制器:\n");
    system("lsusb 2>/dev/null | head -10");
    
    printf("\nUSB设备文件:\n");
    system("ls -la /dev/ttyUSB* /dev/ttyACM* 2>/dev/null || echo '  无USB串口设备'");
    
    printf("\n内核USB模块:\n");
    system("lsmod | grep usb | head -5");
}

void usb_print_device_info(const usb_device_info_t *info) {
    if (!info) return;
    
    printf("USB设备信息:\n");
    printf("  厂商ID: 0x%04X\n", info->vendor_id);
    printf("  产品ID: 0x%04X\n", info->product_id);
    printf("  设备类: 0x%02X (%s)\n", info->device_class, usb_class_to_string(info->device_class));
    printf("  速度: %s\n", usb_speed_to_string(info->speed));
    printf("  厂商: %s\n", info->manufacturer[0] ? info->manufacturer : "未知");
    printf("  产品: %s\n", info->product[0] ? info->product : "未知");
    printf("  序列号: %s\n", info->serial_number[0] ? info->serial_number : "未知");
}

int usb_scan_all_devices(void) {
    usb_info_print("扫描所有USB设备...\n");
    
    printf("系统USB设备列表:\n");
    FILE *lsusb = popen("lsusb 2>/dev/null", "r");
    if (lsusb) {
        char line[256];
        int count = 0;
        while (fgets(line, sizeof(line), lsusb)) {
            printf("  %s", line);
            count++;
        }
        pclose(lsusb);
        return count;
    }
    
    return 0;
}

void usb_scan_serial_devices(void) {
    printf("USB串口设备:\n");
    system("ls -la /dev/ttyUSB* /dev/ttyACM* 2>/dev/null || echo '  无USB串口设备'");
}

void usb_scan_storage_devices(void) {
    printf("USB存储设备:\n");
    system("ls -la /dev/sd* 2>/dev/null | grep -E 'sd[a-z]$' || echo '  无USB存储设备'");
}